//package com.zw.cloud.mybatis.plus.interceptor;
//
//import com.zw.cloud.common.utils.bean.BeanUtils;
//import com.zw.cloud.mybatis.plus.cache.ShareCache;
//import lombok.extern.slf4j.Slf4j;
//import net.sf.jsqlparser.expression.Expression;
//import net.sf.jsqlparser.parser.CCJSqlParserUtil;
//import net.sf.jsqlparser.statement.Statement;
//import net.sf.jsqlparser.statement.delete.Delete;
//import net.sf.jsqlparser.statement.select.FromItem;
//import net.sf.jsqlparser.statement.select.PlainSelect;
//import net.sf.jsqlparser.statement.select.Select;
//import net.sf.jsqlparser.statement.update.Update;
//import org.apache.commons.collections4.CollectionUtils;
//import org.apache.ibatis.cache.CacheKey;
//import org.apache.ibatis.executor.Executor;
//import org.apache.ibatis.mapping.*;
//import org.apache.ibatis.plugin.*;
//import org.apache.ibatis.reflection.DefaultReflectorFactory;
//import org.apache.ibatis.reflection.MetaObject;
//import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
//import org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory;
//import org.apache.ibatis.session.ResultHandler;
//import org.apache.ibatis.session.RowBounds;
//import org.springframework.web.context.request.RequestAttributes;
//import org.springframework.web.context.request.RequestContextHolder;
//import org.springframework.web.context.request.ServletRequestAttributes;
//
//import javax.servlet.http.HttpServletRequest;
//import java.time.format.DateTimeFormatter;
//import java.util.List;
//import java.util.Properties;
//import java.util.stream.Collectors;
//
//@Slf4j
//@Intercepts({
//        @Signature( type = Executor.class, method = "update",args = {MappedStatement.class, Object.class}),
//        @Signature(type = Executor.class, method = "query",args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
//        @Signature(type = Executor.class, method = "query",args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class})
//
//})
//public class IbatisAuditDataInterceptor implements Interceptor {
//
//    private ShareCache shareCache;
//
//    private static final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//
//    public IbatisAuditDataInterceptor(ShareCache shareCache) {
//        this.shareCache = shareCache;
//    }
//
//    @Override
//    public Object intercept(Invocation invocation) throws Throwable {
//        // 获取当前执行的SQL语句
//        Object[] args = invocation.getArgs();
//        MappedStatement ms = (MappedStatement) args[0];
//        /**
//         *  通过MetaObject优雅访问对象的属性，这里是访问MappedStatement的属性;
//         *  MetaObject是Mybatis提供的一个用于方便、优雅访问对象属性的对象，通过它可以简化代码
//         *  不需要try/catch各种reflect异常，同时它支持对JavaBean、Collection、Map三种类型对象的操作。
//         */
//        MetaObject msObject =  MetaObject.forObject(ms, new DefaultObjectFactory(), new DefaultObjectWrapperFactory(),new DefaultReflectorFactory());
//        Object parameterObject = args[1];
//        BoundSql boundSql = ms.getBoundSql(parameterObject);
//        String sql = boundSql.getSql();
//        log.info("[IbatisAuditDataInterceptor][intercept]原SQL：{}", sql.replaceAll("\\n", ""));
//        // 获取当前执行的SQL语句的操作类型
//        SqlCommandType sqlCommandType = ms.getSqlCommandType();
//
//        //解析SQL语句
//        Statement statement = CCJSqlParserUtil.parse(sql);
//
//        List<String> orgCodeList = shareCache.queryShareListFromCache("orgCode");
//
//        if(sqlCommandType == SqlCommandType.SELECT && CollectionUtils.isNotEmpty(orgCodeList)) {
//            String orgCodeStr = orgCodeList.stream().collect(Collectors.joining(","));
//            Select selectStatement = (Select) statement;
//            PlainSelect plain = (PlainSelect) selectStatement.getSelectBody();
//            FromItem fromItem = plain.getFromItem();
//            StringBuffer whereSql = new StringBuffer();
//            if (fromItem.getAlias() != null) {
//                whereSql.append(fromItem.getAlias().getName()).append(".org_code in (").append(orgCodeStr).append(")");
//            } else {
//                whereSql.append("org_code in (").append(orgCodeStr).append(")");
//            }
//            Expression where = plain.getWhere();
//            if (where != null) {
//                whereSql.append(" and ( " + where + " )");
//            }
//            Expression expression = CCJSqlParserUtil.parseCondExpression(whereSql.toString());
//            plain.setWhere(expression);
//
//            BoundSql newBoundSql = new BoundSql(ms.getConfiguration(), selectStatement.toString(), boundSql.getParameterMappings(), boundSql.getParameterObject());
//            MappedStatement mappedStatement = copyFromMappedStatement(ms, new BoundSqlSqlSource(newBoundSql));
//            args[0] = mappedStatement;
//            log.info("[IbatisAuditDataInterceptor][intercept]现SQL：{}", selectStatement.toString().replaceAll("\\n", ""));
//        }else if(sqlCommandType == SqlCommandType.INSERT){
//            /*if(parameterObject instanceof TimeEntity){
//                BeanUtils.setProperty(parameterObject, "time", dtf.format(LocalDateTime.now()));
//                BeanUtils.setProperty(parameterObject, "pid", pid);
//            }*/
//        }else if(sqlCommandType == SqlCommandType.UPDATE){
//            /*if(parameterObject instanceof TimeEntity){
//                BeanUtils.setProperty(parameterObject, "time", dtf.format(LocalDateTime.now()));
//            }
//            Update updateStatement = (Update) statement;
//            Expression where = updateStatement.getWhere();
//            StringBuffer whereSql = new StringBuffer();
//            if (where != null) {
//                whereSql.append("pid = ").append(pid).append(" and ( " + where + " )");
//            }else{
//                whereSql.append("pid = ").append(pid);
//            }
//            Expression expression = CCJSqlParserUtil.parseCondExpression(whereSql.toString());
//            updateStatement.setWhere(expression);
//            BoundSql newBoundSql = new BoundSql(ms.getConfiguration(), updateStatement.toString(), boundSql.getParameterMappings(), boundSql.getParameterObject());
//            MappedStatement mappedStatement = copyFromMappedStatement(ms, new BoundSqlSqlSource(newBoundSql));
//            args[0] = mappedStatement;
//            log.info("[IbatisAuditDataInterceptor][intercept]现SQL：{}", updateStatement.toString().replaceAll("\\n", ""));*/
//        }else if(sqlCommandType == SqlCommandType.DELETE){
//            /*Delete deleteStatement = (Delete) statement;
//            Expression where = deleteStatement.getWhere();
//            StringBuffer whereSql = new StringBuffer();
//            if (where != null) {
//                whereSql.append("pid = ").append(pid).append(" and ( " + where + " )");
//            }else{
//                whereSql.append("pid = ").append(pid);
//            }
//            Expression expression = CCJSqlParserUtil.parseCondExpression(whereSql.toString());
//            deleteStatement.setWhere(expression);
//            BoundSql newBoundSql = new BoundSql(ms.getConfiguration(), deleteStatement.toString(), boundSql.getParameterMappings(), boundSql.getParameterObject());
//            MappedStatement mappedStatement = copyFromMappedStatement(ms, new BoundSqlSqlSource(newBoundSql));
//            args[0] = mappedStatement;
//            log.info("[IbatisAuditDataInterceptor][intercept]现SQL：{}", deleteStatement.toString().replaceAll("\\n", ""));*/
//        }
//        return invocation.proceed();
//    }
//
//
//    @Override
//    public Object plugin(Object o) {
//        return Plugin.wrap(o, this);
//    }
//
//    @Override
//    public void setProperties(Properties properties) {
//
//    }
//
//
//    private MappedStatement copyFromMappedStatement(MappedStatement ms, SqlSource newSqlSource) {
//        MappedStatement.Builder builder = new MappedStatement.Builder(
//                ms.getConfiguration(), ms.getId(), newSqlSource, ms.getSqlCommandType());
//        builder.resource(ms.getResource());
//        builder.fetchSize(ms.getFetchSize());
//        builder.statementType(ms.getStatementType());
//        builder.keyGenerator(ms.getKeyGenerator());
//        if(ms.getKeyProperties() != null && ms.getKeyProperties().length > 0)builder.keyProperty(String.join(",", ms.getKeyProperties()));
//        builder.timeout(ms.getTimeout());
//        builder.parameterMap(ms.getParameterMap());
//        builder.resultMaps(ms.getResultMaps());
//        builder.resultSetType(ms.getResultSetType());
//        builder.cache(ms.getCache());
//        builder.flushCacheRequired(ms.isFlushCacheRequired());
//        builder.useCache(ms.isUseCache());
//        return builder.build();
//    }
//
//    private static class BoundSqlSqlSource implements SqlSource {
//        private final BoundSql boundSql;
//
//        BoundSqlSqlSource(BoundSql boundSql) {
//            this.boundSql = boundSql;
//        }
//
//        @Override
//        public BoundSql getBoundSql(Object parameterObject) {
//            return boundSql;
//        }
//    }
//
//    private HttpServletRequest getHttpServletRequest() {
//        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
//        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
//        return sra.getRequest();
//    }
//}
